package cn.csc.module.shoppingCard.dal.mysql.card;

import cn.csc.framework.common.pojo.PageResult;
import cn.csc.framework.mybatis.core.mapper.BaseMapperX;
import cn.csc.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.csc.framework.mybatis.core.query.LambdaUpdateWrapperX;
import cn.csc.module.shoppingCard.controller.admin.card.vo.CardExportReqVO;
import cn.csc.module.shoppingCard.controller.admin.card.vo.CardPageReqVO;
import cn.csc.module.shoppingCard.dal.dataobject.card.CardDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;

import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 购物卡主表 Mapper
 *
 * @author liuchuang
 */
@Mapper
public interface CardMapper extends BaseMapperX<CardDO> {

    default PageResult<CardDO> selectPage(CardPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<CardDO>()
                .eqIfPresent(CardDO::getProjectId, reqVO.getProjectId())
                .eqIfPresent(CardDO::getCardNumber, reqVO.getCardNumber())
                .eqIfPresent(CardDO::getUserId, reqVO.getUserId())
                .eqIfPresent(CardDO::getUserPhone, reqVO.getUserPhone())
                .eqIfPresent(CardDO::getStatus, reqVO.getStatus())
                .betweenIfPresent(CardDO::getExpireTime, reqVO.getExpireTime())
                .betweenIfPresent(CardDO::getActivatedAt, reqVO.getActivatedAt())
                .betweenIfPresent(CardDO::getCreateTime, reqVO.getCreateTime())
                .isNull(reqVO.getActivated() != null && !reqVO.getActivated(), CardDO::getUserId)
                .isNotNull(reqVO.getActivated() != null && reqVO.getActivated(), CardDO::getUserId)
                .orderByDesc(CardDO::getCreateTime));
    }

    default List<CardDO> selectList(CardExportReqVO reqVO) {
        return selectList(new LambdaQueryWrapperX<CardDO>()
                .eqIfPresent(CardDO::getProjectId, reqVO.getProjectId())
                .eqIfPresent(CardDO::getUserId, reqVO.getUserId())
                .eqIfPresent(CardDO::getUserPhone, reqVO.getUserPhone())
                .eqIfPresent(CardDO::getStatus, reqVO.getStatus())
                .betweenIfPresent(CardDO::getExpireTime, reqVO.getExpireTime())
                .betweenIfPresent(CardDO::getActivatedAt, reqVO.getActivatedAt())
                .betweenIfPresent(CardDO::getCreateTime, reqVO.getCreateTime())
                .isNull(reqVO.getActivated() != null && !reqVO.getActivated(), CardDO::getUserId)
                .isNotNull(reqVO.getActivated() != null && reqVO.getActivated(), CardDO::getUserId)
                .orderByDesc(CardDO::getCreateTime));
    }

    default List<CardDO> selectListByUserId(BigInteger userId) {
        return selectList(new LambdaQueryWrapperX<CardDO>()
                .eqIfPresent(CardDO::getUserId, userId)
                .orderByDesc(CardDO::getCreateTime)
        );
    }

    /**
     * 通过ID列表查询
     * 只查询某些字段
     * @param ids
     * @return
     */
    default List<CardDO> selectListByIds(List<BigInteger> ids) {
        return selectList(new LambdaQueryWrapperX<CardDO>()
                .select(CardDO::getId, CardDO::getProjectId, CardDO::getCardNumber)
                .in(CardDO::getId, ids)
        );
    }

    /**
     * 通过购物卡项目ID查询
     * 只查询某些字段
     * @param projectId 购物卡项目ID
     */
    default List<CardDO> selectListByProjectId(BigInteger projectId) {
        return selectList(new LambdaQueryWrapperX<CardDO>()
                .select(CardDO::getId, CardDO::getProjectId, CardDO::getFaceValue, CardDO::getBalance)
                .eq(CardDO::getProjectId, projectId)
        );
    }

    default CardDO selectByCardNumber(String cardNumber) {
        return selectOne(new LambdaQueryWrapperX<CardDO>()
                .eq(CardDO::getCardNumber, cardNumber)
        );
    }

    /**
     * 锁定购物卡
     */
    default int lockCard(BigInteger userId, BigInteger cardId, BigInteger orderId) {
        LambdaUpdateWrapper<CardDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CardDO::getLockOrder, orderId);
        updateWrapper.eq(CardDO::getUserId, userId);
        updateWrapper.eq(CardDO::getId, cardId);
        updateWrapper.isNull(CardDO::getLockOrder);
        return update(null, updateWrapper);
    }

    /**
     * 解锁购物卡
     */
    default int unLockCard(BigInteger userId, BigInteger cardId, BigInteger orderId) {
        LambdaUpdateWrapper<CardDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CardDO::getLockOrder, null);
        updateWrapper.eq(CardDO::getUserId, userId);
        updateWrapper.eq(CardDO::getId, cardId);
        updateWrapper.eq(CardDO::getLockOrder, orderId);
        return update(null, updateWrapper);
    }

    /**
     * 解锁购物卡
     */
    default int unLockCard(BigInteger userId, List<BigInteger> orderIds) {
        LambdaUpdateWrapperX<CardDO> updateWrapper = new LambdaUpdateWrapperX<>();
        updateWrapper.set(CardDO::getLockOrder, null);
        updateWrapper.eqIfPresent(CardDO::getUserId, userId);
        updateWrapper.in(CardDO::getLockOrder, orderIds);
        return update(null, updateWrapper);
    }

    /**
     * 解锁购物卡
     */
    default int unLockCard(List<BigInteger> orderIds) {
        LambdaUpdateWrapper<CardDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CardDO::getLockOrder, null);
        updateWrapper.in(CardDO::getLockOrder, orderIds);
        return update(null, updateWrapper);
    }

    /**
     * 激活购物卡
     */
    default int activate(CardDO cardDO) {
        LambdaUpdateWrapper<CardDO> updateWrapper = new LambdaUpdateWrapper<>();

        updateWrapper.set(CardDO::getUserId, cardDO.getUserId());
        updateWrapper.set(CardDO::getUserPhone, cardDO.getUserPhone());
        updateWrapper.set(CardDO::getActivatedAt, LocalDateTime.now());
        updateWrapper.set(CardDO::getUpdater, cardDO.getUserId());
        updateWrapper.eq(CardDO::getCardNumber, cardDO.getCardNumber());
        return update(null, updateWrapper);
    }


}
